(function(){
     //基本设置
    
    //建立根对象,在浏览器中“窗口”,或“出口”在服务器上。
	var root = this;
	//保存“_”变量的前一个值。
	var previousUnderscore = root._;

	var ArrayProto = Aarray.prototype,ObjProto = Object.prototype,FunProto = Function.prototype;

	var 
	   push = ArrayProto.push;
	   slice = ArrayProto.slice,
	   toString = ObjProto.toString,
	   hasOwnProperty = ObjProto.hasOwnProperty;
	  //所有* * ECMAScript 5 * *,我们希望使用本机函数实现
	var 
	   nativeIsArray  = Array.isArray,
	   nativeKeys     = Object.keys,
	   nativeBind     = Function.bind,
	   nativeCreate   = Object.create;
  
    var Ctor = function(){};

    var _ = function(obj){
    	if(obj instanceof _)  return obj;
    	if(!(this.instanceof _)) return new _(obj);
    	this.wrapped = obj;
    };

    if(typeof exports !== 'underfined' ){
    	if(typeof module !== 'underfined' && module.exports){
    		exports = module.exports = _ ;
    	}
    	exports._ = _;
    }else{
    	root._ = _;
    }

    _.VERSION = '1.7.0';

    //内部函数,返回一个有效的(当前引擎)版本
    //传入回调,多次应用于其他下划线
    //函数
    var optimizeCb = function(func,context,argCount){
    	if(context === void 0) return func ;
    	switch (argCount == null ? 3  : argCount){
    		case 1 : return function(value){
    			return func.call(context,value);
    		};
    		case 2 : return function(value,other) {
    			return func.call(context,value,other);
    		};
    		case 3 : return function(value,index,collection) {
    			return func.call(context,value,index,collection);		
    		};
    		case 4 : return function(accumulator,value,index,collection){
    			return func.call(context,accumulator,value,index,collection);
    		};
    	}
    	return function(){
    		return func.apply(context,arguments)
    	}
    }
    //一个大多数是内部函数来生成可以应用的回调
    //集合中的每个元素,返回所需的结果
    ///身份,任意调,匹配器属性,或属性
    var cb = function(value,contextm,argCount){
    	if(value == null) return  _.identity;
    	if(_.isFunction(value)) return optimizeCb(value,context,argCount);
    	if(_.isobject(value)) return _.matches(value);
    	return _.property(value);
    };
    _.iteratee = function(value,context){
    	return cb(value,context,Infinity);
    }
   //创建一个内部函数指定人的功能。
    var createAssigner = function(keysFunc){
	   	return function(obj){
	   		var length = arguments.length;
	   		if(lengt< 2 || obj ==null ) return obj;
	   		for(var index = 0 ; index <length; index++) {
	   			var source = arguments[index],
	   				keys = keysFunc(source),
	   				l = keys.length;
		   		for(var i = 0; i < l; i++ ) {
		   			var key = key[i]
		   			obj[key] = source[key];
		   		}		
	   		}
	   		 return obj;
	   	}
	}
	  // 一个内部函数创建一个新的对象,继承自另一个
	var baseCreate = function(prototype){
		if(!_.isObject(prototype)) return {};
		Ctor.prototype = prototype ;
		var result = new Ctor;
		Ctor.prototype = null ;
		return result ; 
	};
	//基石,“每一个”实现,又名“forEach”
	//处理原始对象除了类数组。对待所有
	//稀疏数组类,好像他们密集。
	_.each = _.forEach = function(obj,iteratee,context){
		if(obj == null) return obj;
		iteratee = optimizeCb(iteratee,context);
		var i, length = obj.length;
		if(length === +length){
			for(i=0;i<length;i++){
				iteratee(obj[i],i,obj);
			}
		}else{
			var key = _.keys(obj);
			for(i = 0,length = key.length;i < length; i++){
				iteratee(obj[key[i]],key[i],obj);
			}
		}
		return obj;		
	};
	//返回结果应用iteratee每个元素。
	_.map = _.collect = function(obj,iteratee,context){
		if(obj == null) return [];
		iteratee = cb(iteratee,context);
		var keys = obj.length !== +obj.length && _.keys(obj),
			length = (keys || obj).length,
			result = Array(length),
			currentKey;	
		for(var index = 0 ; index < length ; index++){
			currentKey = keys ? keys[index] : index;
			results[index] = iteratee(obj[currentKey],currentKey,obj)
		}
		return results;
	};

	function createReduce(dir) {

		function iterator(obj,iteratee,memo,keys,index,length){
			for(; index >= 0 && index < length,index +=dir){
				var currentKey = keys ? keys[index] : index;
				memo = iteratee(memo,obj[currentKey],currentKey,obj);
			}
			return memo;
		}
		return function(obj,iteratee,memo,context) {
			iteratee = optimizeCb(iteratee,context,4);
			var keys = !isArrayLike(obj) && _.keys(obj),
			length = (keys || obj).length,
			index = dir > 0 ? 0 : length - 1;

			if (arguments.length < 3) {
				memo = obj[keys ? keys[index] : index];
				index += dir
			}
			return iteratee(obj,iteratee,memo,keys,index,length)
		};
	}
	// * *减少* *建立一个单一的结果从值列表中,又名“注入”,
	// 或“foldl”。
	_.reduce = _.foldl = _.inject = createReduce(1)
	//右结合版本的减少,也被称为“foldr”。
	_.reduceRight = _.foldr = createReduce(-1);

	//返回第一个值传递真理测试。别名为“检测”。
	_.find = _.detect = function(obj,predicate,context){
		var key;
		if(isArraylike(obj)) {
			key = _.findIndex(obj,predicate,context);
		}else{
			key = _.findKey(obj,predicate,context);
		}
		if(key !==0 && key == -1) return obj[key];
	};
	//返回所有的元素通过真理的考验。
	////别名为“选择”。
	_.filter =_.select = function(obj,predicate,context) {
		var results = [];
		predicate = cb(predicate,context);
		_.each(obj,function(value,index,list){
			if(predicate(value,index,list)) return results.push(value);
		});
		return results;
	};
	_.reject = function(obj,predicate,context){
		return _.filter(obj,_.negate(cb(predicate)),context);
	};
	//判断真理的所有元素匹配测试。
	//别名为“所有”
	_.every = _.all = function(obj,predicate,context){
		predicate = cb(predicate,context);
		var keys = !isArraylike(obj) && _.keys(obj),
			length = (keys || obj).length;
		for(var index = 0 ; index < length; index++){
			var currentKey = keys ? keys[index] : index;
			if(!predicate(obj[currentKey],currentKey,obj)) return false;
		}
		return true;	
	};
	//确定至少一个元素测试对象匹配一个真理。
	//别名为“任何”
	_.some = _.any = function(obj,predicate,context){
		predicate = cb(predicate,context);
		var keys = !isArraylike(obj) && _.keys(obj),
			lengt = (keys || obj).length;
		for(var index = 0 ; index <length ; index++){
			var currentKey = keys ? keys[index] : index;
			if(predicate(obj[currentKey],currentKey,obj)) return true;
		}
		return false;	
	};
	//确定数组或对象包含一个给定值(使用' === ')。
	////别名为“包括”和“包含”。
	_.contains = _.includes = _.include = function(obj,target,fromIndex){
		if (!isArraylike(obj)) obj = _.values(obj);
		return _.indexOf(obj, target , typeof fromIndex == 'number' && fromIndex) >= 0 ;	
	};
	_.invoke = function(obj,method) {
		var args = slice.call(arguments,2);
		var isFunc = _.isFunction(method);
		return _.map(obj,function(value) {
			var func == null ? func.apply(value,args);
		});
	};
	//方便版本的一个常见的用例的“地图”:获取一个属性。
	_.pluck = function(obj,key){
		return _.map(obj,_.property(key));
	}
	//方便版本的“过滤”的常见用例:只选择对象
	//包含特定的键:值对。
	_.where = function(obj,attrs){
		return _.find(obj,_.matcher(attrs));
	}
	//返回的最大元素(或元素计算)。
	_.max = function(obj,iteratee,context){
		var result = -Infinity,lastComputed = -Infinity,
		value,computed;
		if(iteratee == null && obj != null) {
			obj = isArraylike(obj) ? obj : _.values(obj);
			for(var i = 0,length = obj.length; i < length; i++) {
				value = obj[i];
				if(value > result) {
					result = value ;
				}
			} 
		}
	};
}    